package cn.yu.takeoutbackend.Notification.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.IdUtil;
import cn.yu.takeoutbackend.Notification.entity.NotificationRecord;
import cn.yu.takeoutbackend.Notification.entity.NotificationRule;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

@Service
@Slf4j
public class NotificationService {
    @Autowired
    private NotificationRuleRepository ruleRepository;
    @Autowired
    private NotificationRecordRepository recordRepository;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    /**
     * 通用提醒入口
     * @param bizType 业务类型
     * @param dataSupplier 数据获取函数（返回业务数据列表）
     * @param messageConverter 消息转换函数
     */
    public  <T> void checkAndNotify(String bizType, Supplier<List<T>> dataSupplier,
                               Function<T, String> idExtractor, Function<T, Map<String,Object>> messageConverter) {
       // 1.获取当前业务的提醒规则
        NotificationRule rule = ruleRepository.findByBizType(bizType);
        if (rule == null || !rule.isEnabled()) {
            log.info("当前业务类型{}的提醒规则不存在或未启用", bizType);
            return;
        }
        // 2.获取待处理业务数据
        final List<T> pendingList = dataSupplier.get();

        // 3.过滤不需要提醒的业务数据
        pendingList.forEach(data->{
            final String bizId =  idExtractor.apply(data);
            NotificationRecord record =  recordRepository.findByBizTypeAndBizId(bizType,bizId);

            if(shouldNotify(rule,record)){
                final Map<String, Object> message = messageConverter.apply(data);
               try {
                   // 4.发送提醒
                   messagingTemplate.convertAndSend("/topic/auditQueue", message);
                   log.info("消息发送成功:{}",message);
                   // 5.更新提醒记录
                   updateRecord(record,rule,bizId);
               }catch (Exception e){
                   log.warn("消息发送失败",e);
               }

            }

        });




    }

    private void updateRecord(NotificationRecord record, NotificationRule rule, String bizId) {
        if(record==null){
            record = new NotificationRecord();
            record.setBizType(rule.getBizType());
            record.setBizId(bizId);
            record.setNotifiedCount(0);
            record.setLastNotifiedTime(LocalDateTime.now());
            recordRepository.save(record);
            log.info("记录创建成功:{}",record);
        }else {
            record.setNotifiedCount(record.getNotifiedCount()+1);
            record.setLastNotifiedTime(LocalDateTime.now());
            recordRepository.update(record);
            log.info("记录更新成功:{}",record);
        }
    }

    private boolean shouldNotify(NotificationRule rule, NotificationRecord record) {
        // 1 rule 是否生效
        if (!rule.isEnabled()) {
            return false;
        }

        // 2 record 是否存在
        if (record == null) {
            return true;
        }

        // 是否超过最大提醒次数
        if (record.getNotifiedCount() >= rule.getMaxReminders()) {
            return false;
        }

        // 是否超过提醒间隔时间
        if (record.getLastNotifiedTime() != null &&
                record.getLastNotifiedTime().plusMinutes(rule.getIntervalMinutes()).isAfter(LocalDateTime.now())) {
            return true;
        }

        return true;
    }

}
